﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Windows.Forms;

namespace AirDrive.Companion
{
    public class SystemTrayController
    {
        private NotifyIcon _trayIcon;
        private ContextMenu _trayMenu;

        private EventHandler _ballonClosed;
        private EventHandler _ballonClicked;

        private Icon _waitingIcon;
        private Icon _connectedIcon;

        private AirDriveCompanion _companion;

        public SystemTrayController()
        {
            _companion = new AirDriveCompanion();
            _companion.DriveConnected += _companion_DriveConnected;
            _companion.DriveUpdated += _companion_DriveUpdated;
            _companion.DrivesCleaned += _companion_DrivesCleaned;

            using (Stream str = Assembly.GetExecutingAssembly().GetManifestResourceStream("AirDrive.Companion.Assets.Waiting.ico"))
            {
                _waitingIcon = new Icon(str, 64, 64);
            }

            using (Stream str = Assembly.GetExecutingAssembly().GetManifestResourceStream("AirDrive.Companion.Assets.Connected.ico"))
            {
                _connectedIcon = new Icon(str, 64, 64);
            }

            _trayMenu = new ContextMenu();
            _trayMenu.Popup += _trayMenu_Popup;

            _trayMenu.MenuItems.Add("-");
            MenuItem autoOpenMenu = _trayMenu.MenuItems.Add("Auto open drive");
            autoOpenMenu.Checked = _companion.AutoOpenConnectedDrive;
            autoOpenMenu.Click += (s, e) => autoOpenMenu.Checked = _companion.AutoOpenConnectedDrive = !_companion.AutoOpenConnectedDrive;

            _trayMenu.MenuItems.Add("About").Click += (s, e) => AboutForm.ShowForm();
            _trayMenu.MenuItems.Add("-");
            _trayMenu.MenuItems.Add("Exit", OnExit);
            
            _trayIcon = new NotifyIcon();
            _trayIcon.BalloonTipClosed += _ballonClosed = (s, e) => _companion.JustConnectedDriveIgnored();
            _trayIcon.BalloonTipClicked += _ballonClicked = (s, e) => _companion.OpenJustConnectedDrive();
            _trayIcon.Text = "AirDrive Companion";

            _trayIcon.Icon = _waitingIcon;
            _trayIcon.ContextMenu = _trayMenu;
            _trayIcon.Visible = true;
        }

        public void Show()
        {
            _companion.Start();
        }

        private void _companion_DriveConnected(Drive drive)
        {
            _trayIcon.Icon = _connectedIcon;
            _trayMenu.MenuItems.Add(0, new DriveMenuItem(null, OpenDrive) { Drive = drive });
            _trayIcon.ShowBalloonTip(2000, string.Format("AirDrive '{0}' connected", drive.Name), "Tap here to open it", ToolTipIcon.Info);
        }

        private void _companion_DriveUpdated(Drive drive)
        {
            DriveMenuItem dmi = _trayMenu.MenuItems.OfType<DriveMenuItem>().FirstOrDefault(x => x.Drive.Endpoint.Equals(drive.Endpoint));
            if (dmi != null)
                dmi.Drive = drive;
        }

        private void _companion_DrivesCleaned()
        {
            if (_companion.Drives.Count == 0)
                _trayIcon.Icon = _waitingIcon;
            else
                _trayIcon.Icon = _connectedIcon;
        }

        private void OpenDrive(object sender, EventArgs e)
        {
            DriveMenuItem dmi = sender as DriveMenuItem;
            if (dmi != null)
                _companion.OpenDrive(dmi.Drive);
        }

        private void _trayMenu_Popup(object sender, EventArgs e)
        {
            _companion.ClearOldDrives();

            foreach (DriveMenuItem dmi in _trayMenu.MenuItems.OfType<DriveMenuItem>().Where(x => !_companion.Drives.Contains(x.Drive)).ToArray())
                _trayMenu.MenuItems.Remove(dmi);
        }

        private void OnExit(object sender, EventArgs e)
        {
            _companion.DriveConnected -= _companion_DriveConnected;
            _companion.DriveUpdated -= _companion_DriveUpdated;
            _companion.Close();

            _trayIcon.Visible = false;
            _trayIcon.BalloonTipClosed -= _ballonClosed;
            _trayIcon.BalloonTipClicked -= _ballonClicked;

            _trayMenu.Popup -= _trayMenu_Popup;

            Application.Exit();
        }
    }
}
